/*
Kakine
ActionScript Framework
Copyright © 2011, PUNY, LLC.

This file is part of KAKINE.

KAKINE is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

KAKINE is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with KAKINE.  If not, see <http://www.gnu.org/licenses/>.
*/ 
package com.puny.mvc.views.platformer
{
	import com.puny.mvc.views.View;
	import com.puny.utils.ExpressionParser;
	import com.puny.xmlutils.XMLReader;
	
	import flash.display.DisplayObject;
	import flash.display.MovieClip;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	
	/**
	 * $Revision: 706 $
	 * ItemView class for a platformer project. The item should be fixed on the platform.
	 * The following attributes in a given xml element can effect its appearance.
	 * <ul>
	 * <li>src</li>
	 * <li>name</li>
	 * <li>x</li>
	 * <li>y</li>
	 * <li>repeatX</li>
	 * <li>repeatY</li>
	 * </ul>
	 * The following constant can be used in x and y attributes.
	 * <ul>
	 * <li>left...this is always zero(0).</li>
	 * <li>top...this is always zero(0).</li>
	 * <li>right...this is a screen width.</li>
	 * <li>bottom...this is a screen height.</li>
	 * <li>width...this is a loaded item width. It's should be a repeated value if a repeatX attribute is valid.</li>
	 * <li>height...this is a loaded item height. It's should be a repeated value if a repeatY attribute is valid.</li>
	 * </ul>
	 */
	public class ItemView extends View
	{
		private const LEFT_OR_TOP:RegExp = /left|top/ig;
		private const RIGHT:RegExp = /right/ig;
		private const BOTTOM:RegExp = /bottom/ig;
		private const WIDTH:RegExp = /width/ig;
		private const HEIGHT:RegExp = /height/ig;
		private var _item:XML;
		private var _thru:Boolean;
		private var _vectors:Array =  [new Point(),
									  new Point(),
									  new Point(),
									  new Point()];
		public function ItemView(item:XML)
		{
			_item = item;
			super(_item.@url);
		}
		
		public function get definition():XML {
			return _item;
		}
		
		override protected function setup():void {
			var countX:int = (_item.@repeatX > 0) ? _item.@repeatX : 1;
			var countY:int = (_item.@repeatY > 0) ? _item.@repeatY : 1;
			var mc:MovieClip;
			for(var iy:int = 0;iy < countY;iy++) {
				for(var ix:int = 0;ix < countX;ix++) {
					mc = getMovieClip(_item.@name);
					mc.x = mc.width * ix;
					mc.y = mc.height * iy;
				}
			}
			_thru = XMLReader.attributeBoolean(_item, "thru");
//			if (_thru) {
//				trace(_item);
//			}
		}
		override public function beforeReady():void {
			x = parse(_item.@x);
			y = parse(_item.@y);
		}
		
		public function get canThru():Boolean {
			return _thru;
		}
		
		private function parse(value:String):Number {
			var str:String = value.replace(LEFT_OR_TOP, "0");
			str = str.replace(RIGHT, stage.stageWidth.toString());
			str = str.replace(BOTTOM, stage.stageHeight.toString());
			str = str.replace(WIDTH, this.width.toString());
			str = str.replace(HEIGHT, this.height.toString());
			var num:Number = ExpressionParser.calculate(str);
			if (isNaN(num)) {
				throw new SyntaxError("\"" + value + "\" includes non-number.");
			}
			return num;
		}
		
		public function getCollisionVector(target:DisplayObject):Array {
			var rect:Rectangle = getBounds(parent);
			rect.x -= target.width;
			rect.y -= target.height;
			rect.width += target.width;
			rect.height += target.height;
			
			_vectors[0].x = target.x - rect.x;
			_vectors[0].y = target.y - rect.y;
			_vectors[1].x = target.x - rect.right;
			_vectors[1].y = _vectors[0].y;
			_vectors[2].x = _vectors[1].x;
			_vectors[2].y = target.y - rect.bottom;
			_vectors[3].x = _vectors[0].x;
			_vectors[3].y = _vectors[2].y;
			return _vectors;
		}
		
		override public function beforeClose():void {
			var i:int = 0;
			var mc:MovieClip;
			for (i = 0;i < numChildren;i++) {
				mc = getChildAt(i) as MovieClip;
				if (mc !=null) {
					mc.gotoAndPlay("close");
				}
			}
		}
		
		override public function procedureClose():Boolean {
			var all:Boolean = false;
			var i:int = 0;
			var mc:MovieClip;
			for (i = 0;i < numChildren;i++) {
				mc = getChildAt(i) as MovieClip;
				if (mc != null) {
					if (mc.currentFrame == mc.totalFrames) {
						mc.stop();
					} else {
						all = true;
					}
				}
			}
			return all;
		}
		
	}
}